﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace Qreed.Windows.ComponentModel
{
    /// <summary>
    /// This is the <see cref="ExpandableObjectConverter"/> for the <see cref="PropertyBagExpandableItem"/>.
    /// </summary>
    public class PropertyBagExpandableItemConverter : ExpandableObjectConverter
    {
        /// <summary>
        /// Converts the given object to the type of this converter, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
        /// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
        /// <returns>
        /// An <see cref="T:System.Object"/> that represents the converted value.
        /// </returns>
        /// <exception cref="T:System.NotSupportedException">
        /// The conversion cannot be performed.
        /// </exception>
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            PropertyBagItemDescriptor prop = (PropertyBagItemDescriptor)context.PropertyDescriptor;
            PropertyBagExpandableItem expandableItem = (PropertyBagExpandableItem)prop.Item;

            if (value.GetType() == typeof(string) && expandableItem.ChildType != typeof(string))
                value = value.ToString().Trim();

            value = Convert.ChangeType(value, expandableItem.Type);

            return value.ToString(); //  Convert.ChangeType(value, expandableItem.Type);
        }

        /// <summary>
        /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
        /// <param name="sourceType">A <see cref="T:System.Type"/> that represents the type you want to convert from.</param>
        /// <returns>
        /// true if this converter can perform the conversion; otherwise, false.
        /// </returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            PropertyBagItemDescriptor prop = (PropertyBagItemDescriptor)context.PropertyDescriptor;
            PropertyBagExpandableItem expandableItem = (PropertyBagExpandableItem)prop.Item;

            if (sourceType == expandableItem.ChildType || sourceType == typeof(string))
                return true;

            return base.CanConvertFrom(context, sourceType);
        }

        /// <summary>
        /// Gets a collection of properties for the type of object specified by the value parameter.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
        /// <param name="value">An <see cref="T:System.Object"/> that specifies the type of object to get the properties for.</param>
        /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that will be used as a filter.</param>
        /// <returns>
        /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> with the properties that are exposed for the component, or null if there are no properties.
        /// </returns>
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            PropertyBagItemDescriptor prop = (PropertyBagItemDescriptor)context.PropertyDescriptor;
            PropertyBagExpandableItem item = (PropertyBagExpandableItem)prop.Item;

            return item.Items.GetProperties(attributes);
        }
    }
}
